//package com.arron.tomcat.connector1.processor;
//
//import com.arron.tomcat.connector1.RequestUtil;
//import com.arron.tomcat.connector1.header.HttpHeader;
//import com.arron.tomcat.connector1.http.HttpConnector;
//import com.arron.tomcat.connector1.http.HttpRequestLine;
//import com.arron.tomcat.connector1.http.StringManager;
//import com.arron.tomcat.connector1.request.HttpRequest;
//import com.arron.tomcat.connector1.request.SocketInputStream;
//import com.arron.tomcat.connector1.response.HttpResponse;
//
//import javax.servlet.ServletException;
//import javax.servlet.http.Cookie;
//import java.io.IOException;
//import java.io.OutputStream;
//import java.net.Socket;
//
//public class HttpProcessor {
//
//
//    StringManager sm = StringManager.getManager("");
//
//    private HttpRequestLine requestLine = new HttpRequestLine();
//
//    HttpRequest httpRequest;
//
//    HttpResponse httpResponse;
//
//
//    HttpConnector httpConnector;
//
//    public HttpProcessor(HttpConnector httpConnector) {
//        this.httpConnector = httpConnector;
//    }
//
//    public void process(Socket socket){
//        OutputStream outputStream= null;
//        SocketInputStream inputStream = null;
//        try {
//            inputStream =  new SocketInputStream(socket.getInputStream(),2048);
//            httpRequest = new HttpRequest(inputStream);
//            outputStream = socket.getOutputStream();
//
//            httpResponse = new HttpResponse(outputStream);
//
//
//            httpResponse.setHeader("Server","demo Servlet Container");
//
//            //  InputStream流只能从头读到尾，所以 parseRequest、parseHeaders 的先后顺序不能反。
//
//            //解析请求
//            parseRequest(inputStream,outputStream);
//            //解析请求头
//            parseHeaders(inputStream);
//
//            if(httpRequest.getRequestURI().startsWith("/servlet")){
//                new ServletProcessor().process(httpRequest,httpResponse);
//            }else {
//                new StaticResourceProcessor().process(httpRequest,httpResponse);
//            }
//
//            socket.close();
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//
//    }
//
//
//    /**
//     *  将HTTP请求中的请求头解析出来，放到 protected HashMap headers = new HashMap(); 这个属性里。如果检测到了请求头中有cookie信息，将其取出来往 protected ArrayList cookies = new ArrayList();
//     *  这个属性里放一份。另外 content-length、content-type请求头的值也单独取出来放到了HttpRequest的 contentLength、contentType字段里
//     * @param input
//     */
//    private void parseHeaders(SocketInputStream input) throws IOException, ServletException {
//        while (true) {
//            HttpHeader header = new HttpHeader();
//
//            // 读取下一个header
//            input.readHeader(header);
//            if (header.nameEnd == 0) {
//                if (header.valueEnd == 0) {
//                    return;
//                } else {
//                    throw new ServletException(sm.getString("httpProcessor.parseHeaders.colon"));
//                }
//            }
//
//            String name = new String(header.name, 0, header.nameEnd);
//            String value = new String(header.value, 0, header.valueEnd);
//            httpRequest.addHeader(name, value);
//            // do something for some headers, ignore others.
//            if (name.equals("cookie")) {
//                // 解析出所有cookie
//                Cookie cookies[] = RequestUtil.parseCookieHeader(value);
//                for (int i = 0; i < cookies.length; i++) {
//                    if (cookies[i].getName().equals("jsessionid")) {
//                        // Override anything requested in the URL
//                        if (!httpRequest.isRequestedSessionIdFromCookie()) {
//                            // Accept only the first session id cookie
//                            httpRequest.setRequestedSessionId(cookies[i].getValue());
//                            httpRequest.setRequestedSessionCookie(true);
//                            httpRequest.setRequestedSessionURL(false);
//                        }
//                    }
//                    httpRequest.addCookie(cookies[i]);
//                }
//            } else if (name.equals("content-length")) {
//                int n = -1;
//                try {
//                    n = Integer.parseInt(value);
//                } catch (Exception e) {
//                    throw new ServletException(sm.getString("httpProcessor.parseHeaders.contentLength"));
//                }
//                httpRequest.setContentLength(n);
//            } else if (name.equals("content-type")) {
//                httpRequest.setContentType(value);
//            }
//        } //end while
//    }
//
//
//    /**
//     *  解析请求行的内容，将method、uri、protocol、queryString解析出来，如果uri中包含jsessionid的话，将jsessionid也解析出来
//     * @param inputStream
//     * @param outputStream
//     */
//    private void parseRequest(SocketInputStream inputStream, OutputStream outputStream) throws IOException, ServletException {
//
//        // 从input流中解析出请求行
//        inputStream.readRequestLine(requestLine);
//        String method = new String(requestLine.method, 0, requestLine.methodEnd);
//        String uri = null;
//        String protocol = new String(requestLine.protocol, 0, requestLine.protocolEnd);
//
//        // 校验 request line
//        if (method.length() < 1) {
//            throw new ServletException("Missing HTTP request method");
//        } else if (requestLine.uriEnd < 1) {
//            throw new ServletException("Missing HTTP request URI");
//        }
//        // 判断URI中存不存在query parameters，并解析出真正的URI
//        int question = requestLine.indexOf("?");
//        if (question >= 0) {
//            httpRequest.setQueryString(new String(requestLine.uri, question + 1, requestLine.uriEnd - question - 1));
//            uri = new String(requestLine.uri, 0, question);
//        } else {
//            httpRequest.setQueryString(null);
//            uri = new String(requestLine.uri, 0, requestLine.uriEnd);
//        }
//
//
//        // 判断URI是不是绝对路径中的值 (带HTTP协议头的，例如：http://www.brainysoftware.com/index.html?name=Tarzan)
//        if (!uri.startsWith("/")) {
//            int pos = uri.indexOf("://");
//            // 将协议和 host name 移除出去
//            if (pos != -1) {
//                pos = uri.indexOf('/', pos + 3);
//                if (pos == -1) {
//                    uri = "";
//                } else {
//                    uri = uri.substring(pos);
//                }
//            }
//        }
//
//        // 如果URI中包含jsessionid则将其解析出来，例如：http://localhost:8080/user/login.jsp;jsessionid=CA0CA7E455535994E523B01357B42214?xxxx=xxx
//        String match = ";jsessionid=";
//        int semicolon = uri.indexOf(match);
//        if (semicolon >= 0) {
//            String rest = uri.substring(semicolon + match.length());
//            int semicolon2 = rest.indexOf(';');
//            if (semicolon2 >= 0) {
//                httpRequest.setRequestedSessionId(rest.substring(0, semicolon2));
//                rest = rest.substring(semicolon2);
//            } else {
//                httpRequest.setRequestedSessionId(rest);
//                rest = "";
//            }
//            httpRequest.setRequestedSessionURL(true);
//            uri = uri.substring(0, semicolon) + rest;
//        } else {
//            httpRequest.setRequestedSessionId(null);
//            httpRequest.setRequestedSessionURL(false);
//        }
//
//        // 标准化 URI，对非正常的URI进行修正
//        String normalizedUri = normalize(uri);
//
//        // Set 正确的请求参数
//        httpRequest.setMethod(method);
//        httpRequest.setProtocol(protocol);
//        if (normalizedUri != null) {
//            httpRequest.setRequestURI(normalizedUri);
//        } else {
//            httpRequest.setRequestURI(uri);
//        }
//
//        if (normalizedUri == null) {
//            throw new ServletException("Invalid URI: " + uri + "'");
//        }
//
//
//    }
//
//    private String normalize(String path) {
//        if (path == null)
//            return null;
//        // Create a place for the normalized path
//        String normalized = path;
//
//        // Normalize "/%7E" and "/%7e" at the beginning to "/~"
//        if (normalized.startsWith("/%7E") || normalized.startsWith("/%7e"))
//            normalized = "/~" + normalized.substring(4);
//
//        // Prevent encoding '%', '/', '.' and '\', which are special reserved
//        // characters
//        if ((normalized.indexOf("%25") >= 0)
//                || (normalized.indexOf("%2F") >= 0)
//                || (normalized.indexOf("%2E") >= 0)
//                || (normalized.indexOf("%5C") >= 0)
//                || (normalized.indexOf("%2f") >= 0)
//                || (normalized.indexOf("%2e") >= 0)
//                || (normalized.indexOf("%5c") >= 0)) {
//            return null;
//        }
//
//        if (normalized.equals("/."))
//            return "/";
//
//        // Normalize the slashes and add leading slash if necessary
//        if (normalized.indexOf('\\') >= 0)
//            normalized = normalized.replace('\\', '/');
//        if (!normalized.startsWith("/"))
//            normalized = "/" + normalized;
//
//        // Resolve occurrences of "//" in the normalized path
//        while (true) {
//            int index = normalized.indexOf("//");
//            if (index < 0)
//                break;
//            normalized = normalized.substring(0, index) + normalized.substring(index + 1);
//        }
//
//        // Resolve occurrences of "/./" in the normalized path
//        while (true) {
//            int index = normalized.indexOf("/./");
//            if (index < 0)
//                break;
//            normalized = normalized.substring(0, index) + normalized.substring(index + 2);
//        }
//
//        // Resolve occurrences of "/../" in the normalized path
//        while (true) {
//            int index = normalized.indexOf("/../");
//            if (index < 0)
//                break;
//            if (index == 0)
//                return (null);  // Trying to go outside our context
//            int index2 = normalized.lastIndexOf('/', index - 1);
//            normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
//        }
//
//        // Declare occurrences of "/..." (three or more dots) to be invalid
//        // (on some Windows platforms this walks the directory tree!!!)
//        if (normalized.indexOf("/...") >= 0)
//            return (null);
//
//        // Return the normalized path that we have completed
//        return (normalized);
//
//
//    }
//
//
//}
